﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonClasses.Model;
using Descriptions_DomainModel.Model;

namespace CommonClasses.Services
{
    /// <summary>
    /// Транслятор, используемый при компиляции.
    /// </summary>
    /// <remarks>
    /// Внимание! Транслятор должен быть проинициализирован с помошью метода Initialize каждый раз при смене описания оборудования!
    /// Иначе могут возникнуть проблемы при проверке имён и переводе 
    /// </remarks>
    public interface ITranslatorService
    {
        /// <summary>
        /// Проверить коректность синтаксиса переданного текста
        /// с использованием данного парсера.
        /// </summary>
        /// <returns>
        /// Отчёт о синтаксических ошибках.
        /// </returns>
        /// <param name="sourceCode">
        /// Исходный текст для проверки.
        /// </param>
        /// <param name="parser">Парсер</param>
        /// <param name="transformers">
        /// Преобразователи AS-дерева, которые будут применены к tree перед возвратом
        /// </param>
        /// <param name="tree">
        /// Дерево, полученное при парсинге sourceCode
        /// </param>
        ErrorReport SyntaxCheck(string sourceCode, IFirstStageGrammar parser, IList<IASTTransformer> transformers, out object tree);

        /// <summary>
        /// Проверить семантическую корректность текста программы
        /// (совместимость типов, инициализация переменных и т.д.)
        /// </summary>
        /// <returns>
        /// Отчёт о семантических ошибках.
        /// </returns>
        /// <param name="tree">
        /// Дерево, полученное при парсинге текста программы.
        /// </param>
        ErrorReport SemanticCheck(object tree);

        /// <summary>
        /// Скомпилировать переданную CompilationData
        /// </summary>
        /// <param name="compilationData">
        /// Информация для компиляции.
        /// </param>
        void Translate(ref CompilationData compilationData);

        /// <summary>        
        /// Указать транслятору, какое описание оборудования использовать при компиляции и проверках.
        /// </summary>
        /// <remarks>
        /// Достаточно вызывать только один раз в нескольких случаях 
        /// - при смене описания оборудования, при открытии нового проекта.
        /// Если данный метод не будет вызван, то могут возникнуть проблемы при проверке имён и переводе.
        /// </remarks>
        /// <param name="domainModel">Описание оборудования</param>
        void Initialize(DomainModel domainModel);
    }
}
